﻿Imports System.IO.Ports
Imports System.Threading
Imports System.ComponentModel
Imports System.Runtime.InteropServices

Public Class Transport

#Region "field"
    Public port As SerialPort
    Private _ready As Boolean
#End Region

    <Description("设备是否准备好")>
    Public ReadOnly Property Ready As Boolean
        Get
            Return _ready
        End Get
    End Property

    Public Sub New()
        _ready = False
    End Sub

    ''' <summary>
    ''' 列出可用的串口
    ''' </summary>
    ''' <returns></returns>
    Public Shared Function ListPorts() As ArrayList
        Dim ret As New ArrayList
        For Each p As String In SerialPort.GetPortNames()
            ret.Add(p)
        Next
        Return ret
    End Function

    ''' <summary>
    ''' 启动串口
    ''' </summary>
    ''' <param name="name">串口名称</param>
    ''' <param name="baudrate">波特率</param>
    ''' <returns>是否打开成功</returns>
    Public Function Begin(name As String, baudrate As Integer) As Boolean
        Dim ret As Boolean = False
        Try
            port = New SerialPort(name) With {
                .BaudRate = baudrate,
                .DataBits = 8,
                .Parity = Parity.None,
                .StopBits = StopBits.One
            }
            port.ReadTimeout = 200
            port.Open()
            ret = True
            _ready = True
        Catch ex As Exception
            Console.Write("[Error] ")
            Console.WriteLine(ex.Message)
        End Try
        Return ret
    End Function


    ''' <summary>
    ''' 清空全部缓存
    ''' </summary>
    Public Sub Flush()
        port.DiscardInBuffer()
    End Sub

    Public Sub Close()
        If Ready Then
            port.Close()
            _ready = False
        End If
    End Sub

    ''' <summary>
    ''' 结构体转字节流
    ''' </summary>
    ''' <param name="valStruct">需要被转换的结构体</param>
    ''' <returns>转换结果</returns>
    ''' <remarks></remarks>
    Public Shared Function StructToByte(valStruct As Object) As Byte()
        Return StructToByte(valStruct, Marshal.SizeOf(valStruct))
    End Function

    Public Shared Function StructToByte(valStruct As Object, len As Integer) As Byte()
        Dim _size As Integer = len
        Dim _buffer As IntPtr = Marshal.AllocHGlobal(_size)
        Try
            Marshal.StructureToPtr(valStruct, _buffer, False)
            Dim _bytes(_size - 1) As Byte
            Marshal.Copy(_buffer, _bytes, 0, _size)
            Return _bytes
        Finally
            Marshal.FreeHGlobal(_buffer)
        End Try
    End Function


    ''' <summary>
    ''' 字节流转结构体
    ''' </summary>
    ''' <param name="_bytes">被转换的字节数组</param>
    ''' <param name="_structType">用.GetType()得到的类型</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function ByteToStruct(_bytes As Byte(), _structType As Type) As Object
        Dim _size As Integer = Marshal.SizeOf(_structType)
        Dim _buffer As IntPtr = Marshal.AllocHGlobal(_size)
        Try
            Marshal.Copy(_bytes, 0, _buffer, _size)
            Return Marshal.PtrToStructure(_buffer, _structType)
        Finally
            Marshal.FreeHGlobal(_buffer)
        End Try
    End Function

End Class


